package com.ksc.wordcount.service.impl;

import com.ksc.wordcount.driver.WordCountDriver;
import com.ksc.wordcount.service.UrlTopNAppRequest;
import com.ksc.wordcount.service.UrlTopNAppResponse;
import com.ksc.wordcount.service.UrlTopNResult;
import com.ksc.wordcount.service.UrlTopNService;
import com.ksc.wordcount.task.TaskStatus;
import com.ksc.wordcount.task.TaskStatusEnum;
import org.apache.avro.Schema;
import org.apache.avro.file.DataFileReader;
import org.apache.avro.generic.GenericDatumReader;
import org.apache.avro.generic.GenericRecord;
import org.apache.avro.io.DatumReader;
import org.apache.thrift.TException;

import java.io.*;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.*;

public class UrlTopNServiceImpl implements UrlTopNService.Iface , Serializable {

    private Map<String, List<UrlTopNResult>> resultMap = new HashMap<>();
    private Map<String, Integer> appStatusMap = new HashMap<>();

    private static String projectPath = System.getProperty("user.dir");
    private static String fileSeparator = System.getProperty("file.separator");

    @Override
    public UrlTopNAppResponse submitApp(UrlTopNAppRequest urlTopNAppRequest) throws TException {
        // 模拟提交URL访问频率计算任务
        // 提交任务后，将任务放入
        // 在这里实现实际逻辑并根据需要更新appStatusMap
        // RUNNING(0),FINISHED(1),FAILED(2);
        UrlTopNAppResponse response = new UrlTopNAppResponse();

        String applicationId = urlTopNAppRequest.getApplicationId();
        String inputPath = urlTopNAppRequest.getInputPath();
        String outputPath = urlTopNAppRequest.getOuputPath();
        int topN = urlTopNAppRequest.getTopN();
        int ReduceNumTasks = urlTopNAppRequest.getNumReduceTasks();
        int splitSize = urlTopNAppRequest.getSplitSize();
        appStatusMap.put(applicationId, 0);
        
        String configFilePath = projectPath + fileSeparator + "thriftTask.conf";
        try {
            // 读取原始的urltopn.conf文件内容
            List<String> lines = Files.readAllLines(Paths.get(configFilePath));

            // 构造新的一行数据
            String newLine = applicationId + " " + inputPath + " " + outputPath + " " + topN + " " + ReduceNumTasks + " " + splitSize;

            // 将新的一行数据添加到urltopn.conf的下一行
            lines.add(newLine);

            // 写入更新后的urltopn.conf文件
            Files.write(Paths.get(configFilePath), lines, StandardCharsets.UTF_8);
            
        } catch (IOException e) {
            appStatusMap.put(applicationId,2);
            e.printStackTrace();
        }

        List<UrlTopNResult> urlTopNResults = null;
        boolean dataRead = false;

        while (!dataRead) {
            try {
                urlTopNResults = readAvro(outputPath + File.separator + applicationId + ".avro");
                dataRead = true; // 设置为 true 表示已成功读取数据
            } catch (FileNotFoundException ex) {
                // 处理 FileNotFoundException
                System.out.println("URL TopN结果文件未找到，可能正在计算中，请稍等...");
                appStatusMap.put(applicationId,0);//程序正在执行中
//                ex.printStackTrace();
                // 等待一段时间再尝试读取
                try {
                    Thread.sleep(5000); // 等待 5 秒
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            } catch (Exception e) {
                // 处理其他异常
                e.printStackTrace();
                break; // 停止循环，因为遇到了其他异常
            }
        }

        appStatusMap.put(applicationId,1);
        
        resultMap.put(applicationId,urlTopNResults);
        
        response.setApplicationId(applicationId);
        response.setAppStatus(appStatusMap.get(applicationId));
        return response;
    }

    @Override
    public UrlTopNAppResponse getAppStatus(String applicationId) throws TException {
        // 模拟获取应用程序状态
        UrlTopNAppResponse response = new UrlTopNAppResponse();
        response.setApplicationId(applicationId);

        if (appStatusMap.containsKey(applicationId)) {
            int status = appStatusMap.get(applicationId);
            response.setAppStatus(status);
        } else {
            throw new TException("找不到应用程序ID对应的结果"); // 无效的应用程序ID
        }
        return response;
    }

    @Override
    public List<UrlTopNResult> getTopNAppResult(String applicationId) throws TException {
        // 获取前 N 个结果
        if (resultMap.containsKey(applicationId)) {
            List<UrlTopNResult> results = resultMap.get(applicationId);
            return results;
        } else {
            throw new TException("找不到应用程序ID对应的结果");
        }
    }

    public List<UrlTopNResult> readAvro(String avroFilePath) throws IOException {
        List<UrlTopNResult> urlTopNResults = new ArrayList<>();
//        try {
            File avroFile = new File(avroFilePath);
            DatumReader<GenericRecord> datumReader = new GenericDatumReader<>();
            DataFileReader<GenericRecord> dataFileReader = new DataFileReader<>(avroFile, datumReader);

            Schema schema = dataFileReader.getSchema();
            System.out.println("Avro Schema: " + schema);

            for (GenericRecord record : dataFileReader) {
                String key = record.get("key").toString();
                int value = (int) record.get("value");
                UrlTopNResult urlTopNResult = new UrlTopNResult();
                urlTopNResult.setUrl(key);
                urlTopNResult.setCount(value);
                urlTopNResults.add(urlTopNResult);
            }
            dataFileReader.close();
//        } catch (FileNotFoundException e) {
//            // 没有找到文件，说明还在执行中
//            e.printStackTrace();
//            return null;
//        } catch (IOException e){
//            e.printStackTrace();
//            return null;
//        }
        return urlTopNResults;
    }

}
